package com.rc.web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.google.common.collect.ImmutableMap;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rc.common.constant.Code;
import com.rc.common.constant.CollectType;
import com.rc.common.constant.CommentType;
import com.rc.common.exception.BusinessException;
import com.rc.common.util.PositionUtil;
import com.rc.common.util.RabbitMqHelper;
import com.rc.pojo.dto.activity.BaseLastThreeVO;
import com.rc.pojo.dto.farm.FarmPageQuery;
import com.rc.pojo.dto.farm.PoiFarmDTO;
import com.rc.pojo.dto.farm.UpdateFarmDTO;
import com.rc.pojo.po.Comment;
import com.rc.pojo.po.Farm;
import com.rc.pojo.po.History;
import com.rc.pojo.po.User;
import com.rc.pojo.vo.collect.CollectVO;
import com.rc.pojo.vo.farm.FarmDetailVO;
import com.rc.pojo.vo.farm.FarmPageVO;
import com.rc.pojo.vo.farm.FarmVO;
import com.rc.pojo.vo.farm.PoiFarmVO;
import com.rc.web.converter.FarmConverter;
import com.rc.web.mapper.FarmMapper;
import com.rc.web.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 农场服务实现类
 * 提供农场相关的业务逻辑实现
 */
@Service
// 使用@Lazy注解防止循环依赖
@RequiredArgsConstructor(onConstructor_= {@Lazy})
public class FarmServiceImpl extends ServiceImpl<FarmMapper, Farm> implements FarmService {
    // 农场转换器
    private final FarmConverter farmConverter;
    // 历史记录服务
    private final HistoryService historyService;
    // 收藏服务
    private final CollectService collectService;
    // 评论服务
    private final CommentService commentService;
    // RabbitMQ工具类
    private final RabbitMqHelper rabbitMqHelper;
    // 用户服务
    private final UserService userService;
    // REST模板
    private final RestTemplate restTemplate;

    /**
     * 获取农场详情
     * @param id 农场ID
     * @return 农场详情VO
     */
    @Override
    public FarmDetailVO detail(Long id) {
        Farm farm = mapper.selectOneById(id);

        if (farm == null){
            throw new BusinessException(Code.NO_SUCH_FARM);
        }

        FarmDetailVO vo = farmConverter.toDetail(farm);
        // 检查是否已收藏
        Boolean collect = collectService.isCollect(id, CollectType.FARM);
        vo.setIsCollect(collect);

        // 获取农场管理员信息
        User farmAdmin = userService.getFarmAdmin(id);
        if (farmAdmin != null) {
            vo.setFarmAdminId(farmAdmin.getId());
            vo.setFarmAdminAvatar(farmAdmin.getAvatar());
        }

        // 保存搜索历史
        History history = History.builder().keyword(farm.getName()).build();
        historyService.save(history);
        return vo;
    }

    /**
     * 更新农场信息
     * @param dto 更新农场DTO
     */
    @Override
    public void updateOneById(UpdateFarmDTO dto) {
        // 获取当前用户的农场ID
        Long farmId = StpUtil.getSession().getModel("user", User.class).getFarmId();
        dto.setId(farmId);

        // 转换DTO为PO并更新
        Farm farm = farmConverter.updateDTO2PO(dto);
        boolean success= this.updateById(farm);

        if (!success){
            throw new BusinessException(Code.UPDATE_FARM_FAILED);
        }

        // 发送消息更新相关数据
        Map<String, Object> msg = ImmutableMap.<String,Object>builder()
                .put("itemId", farm.getId())
                .put("type", CollectType.FARM)
                .build();

        rabbitMqHelper.sendMessage("item.direct","update", msg);
    }

    /**
     * 获取POI农场信息
     * @param dto POI查询DTO
     * @return POI农场VO列表
     */
    @Override
    public List<PoiFarmVO> getPoi(PoiFarmDTO dto) {
        Double lng = dto.getLng();
        Double lat = dto.getLat();

        // 根据位置查询农场列表
        List<Farm> farmList = mapper.selectByLocation(lng, lat, dto.getDistance(), dto.getType());
        // 演示需要，将德正农庄置顶
        Farm deZheng = farmList.stream().filter(farm -> farm.getId().equals(916L)).findFirst().get();
        int deZhengIndex = farmList.indexOf(deZheng);
        Collections.swap(farmList, deZhengIndex, 0);

        // 获取用户收藏的农场ID列表
        List<Long> collectIdList = collectService.getList(CollectType.FARM)
                .stream()
                .map(CollectVO::getItemId)
                .toList();

        // 获取农场最后三条好评
        List<Long> farmIdList = farmList.stream().map(Farm::getId).toList();
        Map<Long, List<Comment>> lastThreeMap = commentService.getItemLastThreeFavorable(farmIdList, CommentType.FARM);

        return farmList.stream()
                .map(item -> {
                    PoiFarmVO poiFarmVO = farmConverter.toPoi(item);
                    // 设置最后三条好评
                    List<Comment> lastThreeComments = lastThreeMap.get(item.getId());
                    BaseLastThreeVO.set(poiFarmVO, lastThreeComments);

                    // 计算距离
                    poiFarmVO.setDistance(PositionUtil.distance(lng, lat, item.getLng(), item.getLat()));

                    // 判断是否收藏
                    poiFarmVO.setIsCollect(collectIdList.contains(item.getId()));
                    return poiFarmVO;
                })
                // 根据排序条件排序
                .sorted((o1,o2)-> switch (dto.getSort()){
                    case "distance" -> Double.compare(o1.getDistance(),o2.getDistance());
                    case "score" -> Double.compare(o1.getScore(),o2.getScore());
                    case "recommend" -> Integer.compare(o1.getRecommended(),o2.getRecommended());
                    default -> 0;
                })
                .toList();
    }

    /**
     * 分页查询农场
     * @param dto 分页查询条件
     * @return 分页结果
     */
    @Override
    public Page<FarmPageVO> getPage(FarmPageQuery dto) {
        return mapper.selectPage(dto);
    }

    /**
     * 根据ID获取农场信息
     * @param id 农场ID
     * @return 农场VO
     */
    @Override
    public FarmVO getOneById(Long id) {
        Farm farm = this.getById(id);
        return farmConverter.toVO(farm);
    }
}
